<!DOCTYPE html><html lang="ru" dir="ltr" spellcheck><head><!--#include file="h.htm"--><meta name="description" content="Пиццикато Алексея Лота. Полезные высказывания из книги 'Совершенный код' Макконнелла."><meta name="keywords" content="сайт алексея лота, технологии, совершенный код, макконнелла, правила разработки, программного обеспечения, алексей лот"><title>Полезные высказывания из книги "Совершенный код" Макконнелла</title></head><body><header><h1 class=m>Пиццикато Алексея Лота</h1><nav><a href="p.htm">Главная</a><a href="m.htm">Песни</a><a href="l.htm">Психология</a><a href="r.htm">Рассказы</a><a href="b.htm">Религия</a><a href="s.htm">Стихотворения</a><a id="i" href="t.htm">Технологии</a><a href="f.htm">Философия</a><a href="i.htm">Фотография</a></nav></header><article id="c"><h2 class=m>Полезные высказывания из книги "Совершенный код" Макконнелла</h2><div id="w">Средство распространения информации о хороших методиках сыграло бы важную роль.<br><br>Для широкого распространения исследовательских разработок требуется от 5 до 15 и более лет.<br><br>Ежегодно программистами становятся около 50000 человек.<br><br>Число дипломов, вручаемых в отрасли около 35000.<br><br>Единственным способом получения информации является изучение горы книг и нескольких сотен технических журналов, дополненное значительным реальным опытом (о конструировании ПО).<br><br>Сайт книги cc2e.com/1234.<br><br>Конструирование ПО=кодирование.<br><br>На конструирование приходится 65% в больших проектах.<br><br>Во время конструирования допускается от 50 до 75% ошибок в больших проектах.<br><br>Ошибки конструирования дешевле исправлять.<br><br>Одними из самых дорогих ошибок в истории, приведшими к убыткам в сотни миллионов долларов, были мелкие ошибки кодирования.<br><br>При написании программы только этапа конструирования нельзя избежать.<br><br>Почта и сайт автора stevencc@construx.com, stevemcconnell.com.<br><br>Книги никогда не создаются в одиночку.<br><br>Составляющие разработки ПО за последние 25 лет:<br>- определение проблемы;<br>- выработка требований;<br>- создание плана конструирования;<br>- разработка архитектуры ПО, или высокоуровневое проектирование;<br>- детальное проектирование;<br>- кодирование и отладка;<br>- блочное тестирование;<br>- интеграционное тестирование;<br>- интеграция;<br>- тестирование системы;<br>- корректирующее сопровождение.<br><br>Проекты бывают формальные, неформальные.<br><br>Конструирование не включает определение проблемы.<br><br>Конструирование=программирование.<br><br>В центре конструирования - кодирование и отладка.<br><br>Конкретные задачи, связанные с конструированием:<br>1.Проверка выполнения условий, необходимых для успешного конструирования;<br>2.Определение способов последующего тестирования кода;<br>3.Проектирование и написание классов и методов;<br>4.Создание и присвоение имён переменным и именованным константам;<br>5.Выбор управляющих структур и организация блоков команд;<br>6.Блочное тестирование, интеграционное тестирование и отладка собственного кода;<br>7.Взаимный обзор кода и низкоуровневых программных структур членами группы;<br>8."Шлифовка" кода путём его тщательного форматирования и комментирования;<br>9.Интеграция программных компонентов, созданных по отдельности;<br>10.Оптимизация кода, направленная на повышение его быстродействия, и снижение степени использования ресурсов.<br><br>В конструирование не входят управление, выработка требований, разработка архитектуры, проектирование пользовательского интерфейса, тестирование системы и её сопровождение.<br><br>На конструирование обычно уходит 30-80% времени работы.<br><br>Требования к приложению и архитектура разрабатываются, чтобы гарантировать эффективность этапа конструирования.<br><br>Тестирование системы выполняется после конструирования, чтобы проверить его правильность.<br><br>Производительность труда отдельных программистов во время конструирования изменяется в 10-20 раз.<br><br>Исходный код - самая свежая документация на ПО.<br><br>Тестирование системы должно контролироваться статистически.<br><br>Повышение эффективности конструирования позволяет оптимизировать любой проект.<br><br>Компетентность в конструировании ПО определяет то, насколько хороший вы программист.<br><br>Метафоры позволяют лучше понять разработку ПО.<br><br>Использование метафор (аналогий) - моделирование.<br><br>Эффективность моделей объясняется их яркостью и концептуальной целостностью.<br><br>При чрезмерном обобщении модели вводят в заблуждение.<br><br>Хорошие метафоры простые, согласуются с другими метафорами и объясняют многие данные и явления.<br><br>Описываемое метафорами поведение предсказуемо и понятно всем людям.<br><br>Самая сложная часть программирования - концептуализация проблемы.<br><br>90% общего объёма работы на программной системой выполняется после выпуска первой версии.<br><br>Популярные метафоры о разработке ПО:<br>1.Написание письма;<br>2.Выращивание сельскохозяйственных культур;<br>3.Процесс формирования жемчужины;<br>4.Построение дома (невыгодно писать компоненты, которые можно купить готовыми).<br><br>Программная система из 1 млн строк требует 69 видов документации, спецификация требований занимает 4000-5000 страниц.<br><br>В неудачных проектах конструирование приходится выполнять несколько раз.<br><br>Вайнберг "The psychology of computer programming".<br><br>Хороших программистов всегда не хватает.<br><br>Последовательный подход (вопросы решаются заблаговременно) применяется, когда:<br>- требования довольно стабильны;<br>- проект приложения прост и относительно понятен;<br>- группа разработчиков знакома с прикладной областью;<br>- проект не связан с особым риском;<br>- важна долговременная предсказуемость проекта;<br>- затраты на изменение требований, проекта приложения и кода скорее всего окажутся высокими.<br><br>Итеративный подход (вопросы решаются по мере работы) применяется, когда:<br>- требования относительно непонятны или вам кажется, что они могут оказаться нестабильными по другим причинам;<br>- проект приложения сложен, не совсем ясен или и то и другое;<br>- группа разработчиков незнакома с прикладной областью;<br>- проект сопряжен с высоким риском;<br>- долговременная предсказуемость проекта не играет особой роли;<br>- затраты на изменение требований, проекта приложения и кода скорее всего будут низкими.<br><br>Итеративные подходы эффективны чаще.<br>Предварительное условие: ясное формулирование проблемы, которую система должна решать (без намёка на решение).<br><br>Процесс программирования:<br>1) Определение проблемы;<br>2) Выработка требований;<br>3) Проектирование архитектуры;<br>4) Конструирование;<br>5) Тестирование системы;<br>6) Будущие улучшения;<br><br>Проблема должна быть описана с пользовательской точки зрения (без компьютерных терминов).<br><br>Требования подробно описывают, что должна делать программная система.<br><br>Функциональность системы определяется пользователем, а не программистом (требования решают споры, сводят к минимуму изменения системы после начала разработки, снижают дополнительные расходы).<br><br>Процесс разработки помогает разработчикам и клиентам лучше понять свои потребности.<br><br>В среднем проекте требования во время разработки изменяются на 25%, на что приходится 80% повторной работы над проектом.<br><br>Изменение требований влечёт пересмотр графика и сметы.<br><br>evolutionary prototyping - поставка системы клиенту по частям.<br><br>Определить моменты прекращения работы над проектом.<br><br>Архитектура описывает какие другие компоненты данный компонент может использовать непосредственно, какие косвенно, а какие вообще не должен использовать; должна описывать организацию классов в подсистемы и обосновывать итоговый вариант.<br><br>Интерфейс проектируется на этапе выработки требований либо в архитектуре.<br><br>Архитектура должна быть модульной.<br><br>Архитектура определяет подходы к безопасности.<br><br>В требованиях определяются показатели производительности.<br><br>Масштабируемость - возможность системы адаптироваться к росту требований.<br><br>Интернационализация - реализация в программе поддержки региональных стандартов.<br><br>Локализация - перевод интерфейса программы и реализация в ней поддержки конкретного языка.<br><br>Архитектура выражает отношение к избыточной функциональности.<br><br>Архитектура чётко описывает стратегию изменений.<br><br>В архитектуре должны быть обоснованы важнейшие принятые решения.<br><br>Цели должны быть чётко сформулированы.<br><br>В архитектуре явно определены области риска, указаны его причины и описаны действия по сведению риска к минимуму.<br><br>В проекте без проблем работа над требованиями, архитектурой и предварительным планированием поглощает 20-30% времени.<br><br>Программисты, использующие язык, с которым они работали три года или более, примерно на 30% более продуктивны, чем программисты, обладающие аналогичным опытом, но для которых язык является новым.<br><br>Программисты, использующие языки высокого уровня, достигают более высокой производительности и создают более качественный код, чем программисты, работающие с языками низкого уровня.<br><br>Гипотеза Сапира-Уорфа: способность человека к обдумыванию определённых мыслей зависит от знания слов, при помощи которых можно выразить эту мысль.<br><br>Ada, Cobol используются в Минобороны США.<br><br>SQL - декларативный язык.<br><br>Программируют с использованием языка, а не на языке.<br><br>Важный аспект работы проектировщика - анализ конкурирующих характеристик проекта и достижение баланса между ними.<br><br>Спроектировать программу можно десятками разных способов.<br><br>Существенные свойства - которыми объект должен обладать, чтобы быть именно этим объектом.<br><br>Несущественные (акцидентные) свойства - которые не влияют на суть объекта.<br><br>Управление сложностью - самый важный аспект разработки ПО.<br><br>Э. Дейкстра: ни один человек не обладает интеллектом, способным вместить все детали современной компьютерной программы.Поэтому целью является минимизация объёма программы, о котором нужно думать в конкретный момент времени.<br><br>Цель всех методик проектирования ПО - разбиение сложной проблемы на простые фрагменты.<br><br>Краткость методов помогает снизить нагрузку на интеллект.<br>Этому же способствует написание программы в терминах проблемной области, а также работа на самом высоком уровне абстракции.<br><br>Как бороться со сложностью? Чаще всего причинами неэффективности являются:<br>- сложное решение простой проблемы;<br>- простое, но неверное решение сложной проблемы;<br>- неадекватное сложное решение сложной проблемы.<br><br>Дейкстра: сложность современного ПО обусловлена самой его природой.<br><br>Двойственный подход к управлению сложностью:<br>-старайтесь свести к минимуму объём существенной сложности, с которым придётся работать в каждый конкретный момент времени;<br>-сдерживайте необязательный рост несущественной сложности.<br><br>Внутренние характеристики проекта:<br>- минимальная сложность;<br>- простота сопровождения;<br>- слабое сопряжение;<br>- расширяемость;<br>- возможность повторного использования;<br>- система предусматривает интенсивное использование вспомогательных низкоуровневых классов;<br>- класс использует минимальное число других классов;<br>- портируемость;<br>- минимальная, но полная функциональность (дополнительный код необходимо разработать, проанализировать, протестировать, пересматривать при изменении других фрагментов программы, поддерживать совместимость будущих версий с дополнительным кодом);<br>- систему можно изучать на отдельных уровнях, игнорируя другие уровни (проектировать дополнительный уровень, скрывающий плохое качество старого кода);<br>- соответствие стандартным популярным подходам.<br><br>Уровни детальности проектирования программной системы:<br>-вся система;<br>-разделение системы на подсистемы или пакеты определение взаимодействий между ними (минимальные взаимодействия для облегчения модификации (проще сначала ограничить взаимодействие, а затем сделать его более свободным)).<br><br>Отношения между системами должны быть простыми.<br>В порядке уменьшения простоты:<br>1) Одна подсистема вызывает методы другой;<br>2) Одна подсистема содержит классы другой;<br>3) Наследование классов одной подсистемы от классов другой.<br><br>Программа не должна содержать циклических отношений.<br><br>Часто используемые подсистемы:<br>-бизнес-правил;<br>-пользовательского интерфейса;<br>-доступа к БД;<br>-изоляции зависимостей от ОС.<br><br>Разделение подсистем на классы обычно требуется во всех проектах.<br><br>Объект - динамическая сущность, класс - статическая.<br><br>БД: различие между классом и объектом аналогично различию между "схемой" и "экземпляром".<br><br>Разделение классов на методы необходимо в каждом проекте и часто оставляется отдельным программистам.<br><br>Проектирование методов может включать написание псевдокода, поиск алгоритмов в книгах, размышление над оптимальной организацией фрагментов метода и написание кода.<br><br>При проектировании с использованием искусственных объектов и объектов реального мира определите:<br>-объекты и их атрибуты (методы и данные);<br>-действия, которые могут быть выполнены над каждый объектом;<br>-действия, которые каждый объект может выполнять над другими объектами (включение и наследование);<br>-части каждого объекта, видимые другим объектам, то есть открытые и закрытые части;<br>-открытый интерфейс каждого объекта (на уровне языка программирования).<br><br>Открытый интерфейс - данные и методы, которые объект предоставляет в распоряжение остальным объектам.<br><br>Защищённый интерфейс - части объекта, доступные производным от него объектам.<br><br>2 вида итерации:<br>-высокоуровневая, направленная на улучшение организации классов;<br>-на уровне определённых классов, направленная на детализацию проекта каждого класса.<br><br>Дом - абстракция его составляющих.<br>Абстракция - один из главных способов борьбы со сложностью реального мира.<br><br>Абстракция позволяет задействовать концепцию, игнорируя её некоторые детали и работая с разными деталями на разных уровнях.<br><br>Создавать абстракции на уровне интерфейсов методов, интерфейсов классов и интерфейсов пакетов.<br><br>Инкапсуляция не только представляет сложную концепцию в более простой форме, но и не позволяет взглянуть на какие бы то ни было детали сложной концепции.<br><br>Наследование позволяетсоздать универсальные методы для выполнения всего, что основано на общих свойствах дверей, и затем написать специфические методы для выполнения специфических операций над конкретными типами дверей.<br><br>Поддержка языком операций вроде Open() или Close() при отсутствии информации о конкретном типе двери вплоть до периода выполнения называется полиморфизмом.<br><br>Интерфейсы классов должны быть полными и минимальными, должны сообщать как можно меньше о внутренней работе класса (класс похож на айсберг, большая часть которого скрыта под водой).<br><br>Разработка интерфейса класса - итеративный процесс (пытаться создать или использовать другой подход).<br><br>Сокрытие аспектов проектирования позволяет значительно уменьшить объём кода, затрагиваемого изменениями (например, применение именованных констант вместо литералов; сокрытие информации: "id=new Id();" вместо "id=++g_maxId;").<br><br>Категории секретов: <br>-секреты, которые скрывают сложность, позволяя программистам забыть о ней при работе над остальными частями программы;<br>-секреты, которые скрывают источники изменений с целью локализации результатов возможных изменений.<br><br>Барьеры, препятствующие сокрытию информации:<br>-избыточное распространение информации (например, использование литералов вместо констант, распространение кода взаимодействия с пользователем по системе - GUI концентрировать в одном классе (пакете, подсистеме));<br>-круговая зависимость (B зависит от А, который зависит от B; не позволяет протестировать один класс, пока не будет готова часть другого);<br>-ошибочное представление о данных класса как о глобальных данных;<br>-кажущееся снижение производительности.<br><br>Крупные программы, использующие сокрытие информации, в 4 раза легче модифицировать, чем программы, его не использующие.<br><br>Размышлять о том, что скрыть.<br><br>Подготовка к изменениям:<br>1.Определите элементы, изменение которых кажется вероятным;<br>2.Изолируйте элементы, изменение которых кажется вероятным.<br><br>Интерфейс класса должен скрывать изменения в классе.<br><br>Области, изменяющиеся чаще всего:<br>-бизнес-правила;<br>-зависимости от оборудования;<br>-ввод-вывод;<br>-нестандартные возможности языка;<br>-сложные аспекты проектирования и конструирования;<br>-переменные статуса.<br><br>В качестве переменных статуса применять не булевы переменные, а перечисления.<br><br>Вместо непосредственной проверки переменной использовать методы доступа.<br><br>Проектировать систему так, чтобы влияние изменений было обратно пропорционально их вероятности.<br>Если изменение маловероятно, но его легко предугадать, рассмотрите его внимательнее, чем более вероятное изменение, которое трудно спланировать.<br><br>Функции, нужные пользователям - ядро системы, которое не потребуется изменять.<br><br>Путём небольших приращений экстраполировать систему, определяя дополнительную часть.<br><br>Сопряжение характеризует силу связи класса или метода с другими классами или методами.<br>Поддерживать сопряжение слабым.<br><br>Слабое сопряжение (loose coupling) - классы и методы имеют немногочисленные, непосредственные, явные и гибкие отношения с другими классами.<br><br>Эффективный механизм соединения максимально прост.<br><br>Отношения модулей должны напоминать отношения деловых партнёров, а не сиамских близнецов.<br><br>Критерии оценки сопряжения:<br>-объём связи (число соединений смежду модулями - число параметров метода, число открытых методов);<br>-видимость (заметность связи между двумя модулями);<br>-гибкость(лёгкость изменения связи между модулями).<br><br>Самые распространённые виды сопряжения:<br>-простое сопряжение посредством данных-параметров (передача элементарных типов данных через списки параметров);<br>-простое сопряжение посредством объекта (модуль создаёт экземпляр объекта, с которым сопряжён);<br>-сопряжение посредством объекта-параметра (объект 1 требует, чтобы объект 2 передал ему объект);<br>-семантическое сопряжение (один модуль использует семантические знания о внутренней работе другого модуля): модуль 1 передаёт в модуль 2 управляющий флаг, определяющий дальнейшую работу модуля 2; модуль 2 использует глобальные данные после их изменения модулем 1; семантическое сопряжение опасно тем, что изменение кода в используемом модуле может так нарушить работу использующего модуля, что компилятор этого не определит.<br><br>Классы и методы должны упрощать работу.<br><br>Шаблоны снижают сложность, предоставляя готовые абстракции, снижают число ошибок, стандартизируя детали популярных решений.<br><br>Шаблоны имеют эвристическую ценность, указывая на возможные варианты проектирования.<br><br>Шаблоны упрощают взаимодействие между разработчиками, позволяя им общаться на более высоком уровне.<br><br>Ловушки шаблонов - насильственная адаптация кода к шаблону, применение шаблона, продиктованное не целесообразностью, а желанием испытать шаблон в деле.<br><br>Шаблоны проектирования - эффективный инструмент управления сложностью.<br><br>Шаблон - это эвристический принцип.<br><br>Связность (cohesion) должна быть максимальна.<br><br>Связность характеризует то, насколько хорошо все методы класса или все фрагменты метода соответствуют главной цели.<br><br>Формируйте иерархии.<br>Иерархия - это многоуровневая структура организации информации, при которой наиболее общая или абстрактная репрезентация концепции соответствует вершине, а более детальные специализированные репрезентации - более низким уровням.<br><br>Люди в целом находят иерархии естественным способом организации сложной информации.<br>Рисуя сложный объект, люди рисуют его иерархически.<br><br>Формализовать контракты классов (обещания клиентов - предусловия, обязательства класса - постусловия).<br><br>Грамотно назначать сферы ответственности.<br><br>Проектировать систему для тестирования.<br><br>Тщательно рассматривать возвожные причины аварий, а не просто копировать другие успешные проекты.<br><br>Тщательно выбирать время присвоения переменной конкретного значения (binding time).<br><br>Создавать центральные точки управления - управление может быть централизовано в классах, методах, макросах препроцессора, файлах библиотек.<br><br>Рисовать диаграммы - они представляют проблему на более высоком уровне абстракции.<br><br>Поддерживать модульность проекта системы - каждый метод или класс должен быть похож на чёрный ящик (известны входы и выходы, но неизвестно что внутри).<br><br>Проектировать ПО нужно с использованием разных подходов.<br><br>Проектирование - итеративный процесс. После его завершения нужно возвращаться к началу.<br><br>Лучше обнаруживать варианты, которые не работают, чем ничего не делать.<br><br>Нисходящее (top-down) проектирование начинается на высоком уровне абстракции.<br>Восходящее (bottom-up) начинается со специфики и постепенно переходит ко всё большей общности.<br><br>Если сейчас решение кажется вам чуть-чуть хитрым, для любого, кто будет работать над ним позднее, оно станет головоломкой.<br><br>Нисходящая стратегия - декомпозиция.<br>Восходящая - композиция.<br><br>Большинство людей находят разбиение крупной концепции на меньшие части более лёгким, чем объединение небольших концепций в более крупную.<br><br>Прототипирование работает плохо, если задача недостаточно конкретна.<br><br>Имена прототипных классов и пакетов должны иметь префикс prototype.<br><br>Механические действия вытесняют творчество.<br><br>Регистрировать протоколы обсуждения проекта и принятые решения при помощи Wiki.<br><br>Отправлять резюме дискуссий всем членам группы по электронной почте.<br><br>Фотографировать схемы на доске.<br><br>Хранить плакаты со схемами проекта.<br><br>Использовать UML.<br><br>Класс - это набор данных и методов, имеющих общую, целостную, хорошо определённую сферу ответственности.<br><br>Классы нужны для максимизации части программы, которую можно игнорировать при работе над конкретными фрагментами кода.<br><br>Абстрактный тип данных - это набор, включающий данные и выполняемые над ними операции (служащие одной цели).<br>Преимущества использования АТД:<br>-возможность сокрытия деталей реализации;<br>-ограничение области изменений;<br>-более высокая информативность интерфейса;<br>-лёгкость оптимизации кода;<br>-лёгкость проверки кода;<br>-удобочитаемость и понятность кода;<br>-ограничение области использования данных;<br>-возможность работы с сущностями реального мира, а не с низкоуровневыми деталями реализации.<br>Принципы использования АТД:<br>-представлять в форме АТД распространённые низкоуровневые типы данных;<br>-представлять в форме АТД часто используемые объекты, такие как файлы;<br>-представлять в форме АТД даже простые элементы;<br>-обращайтесь к АТД так, чтобы это не зависело от среды, используемой для его хранения.<br><br>В ООП каждый АТД можно реализовать как класс (класс дополнительно поддерживает наследование и полиморфизм).<br><br>Интерфейс класса - это абстракция реализации класса, скрытой за интерфейсом.<br>Принципы проектирования интерфейсов:<br>-выражать в интерфейсе класса согласованный уровень абстракции (смешанные уровни<br>абстракции делают программу всё менее и менее понятной);<br>-убедиться в понимании того, реализацией какой абстракции является класс;<br>-представляйте методы вместе с противоположными им методами (создавать противоположные методы, не имея на то причин, не следует);<br>-убирать постороннюю информацию в другие классы;<br>-преобразовывать семантические элементы интерфейса в программные, например, утверждениями (интерфейсы должны как можно меньше зависеть от документации);<br>-элементы интерфейса должны находиться на одном уровне абстракции;<br>-не включать в класс открытые члены, плохо согласующиеся с абстракцией интерфейса;<br>-рассматривать абстракцию и связность вместе.<br><br>Хорошая инкапсуляция:<br>-минимизировать доступность классов и их членов;<br>-не делать данные-члены открытыми;<br>-не включать в интерфейс класса закрытые детали реализации;<br>-класс не должен делать предположений о том, как этот интерфейс будет или не будет использоваться;<br>-избегать использования дружественных классов;<br>-не делать метод открытым лишь потому, что он использует только открытые методы;<br>-ценить лёгкость чтения кода выше, чем удобство его написания;<br>-избегать зависимости клиентского кода от закытой реализации класса, а не от его открытого интерфейса (должен быть интерфейс, позволяющий разобраться не глядя на реализацию);<br>-остерегаться жесткого сопряжения - сильной связи между двумя классами.<br><br>Включение (containment) - один класс содержит примитивный элемент данных или другой класс.<br>Включение проще наследования и меньше подвержено ошибкам.<br>Включение можно реализовать отношением "содержит" (в крайнем случае - закрытое наследование).<br><br>Класс должен содержать 9 примитивных типов или 5 сложных объектов.<br><br>Наследование помогает избегать повторения кода и данных в нескольких местах, централизуя их в базовом классе (один класс является более специализированным вараинтом другого класса).<br><br>Проектировать и документировать классы с учётом возможности наследования или запретить его.<br><br>Наследование повышает сложность программы.<br><br>Все методы базового класса должны иметь в каждом производном классе то же значение.<br><br>Убедиться, что наследуется только то, что нужно.<br><br>Не используйте имена непереопределяемых методов базового класса в производных классах.<br><br>Перемещайте общие интерфейсы, данные и формы поведения на как можно более высокий уровень иерархии наследования, если это не нарушит абстракцию.<br><br>С подозрением относитесь к классам, объекты которых создаются в единственном экземпляре (возможно, класс перепутан с объектом).<br><br>С подозрением относитесь к базовым классам, имеющим только один производный класс.<br><br>С подозрением относитесь к классам, которые переопределяют метод, оставляя его пустым.<br><br>Избегайте многоуровневых иерархий наследования, ограничивая иеррахии наследования максимум 6 уровнями.<br><br>Предпочитайте полиморфизм, а не крупномасштабную проверку типов.<br><br>Делайте все данные закрытыми, а не защищёнными.<br><br>Миксин - простой класс, позволяющий добавлять ряд свойств в другой класс.<br><br>Ромбовидная схема наследования - классическая проблема.<br><br>Используйте множественное наследование, только тщательно рассмотрев все альтернативные варианты и проанализировав влияние выбранного подхода на сложность и понятность системы.<br><br>Ради управления сложностью относитесь к наследованию с подозрением.<br><br>Включайте в класс как можно меньше методов.<br><br>Блокируйте неявные методы и операторы, которые Вам не нужны (private).<br><br>Минимизируйте число разных методов, вызываемых классом.<br><br>Избегайте опосредованных вызовов методов других классов (цепочек вызовов).<br><br>Вообще минимизируйте сотрудничество класса с другими классами.<br><br>Инициализируйте по мере возможности все данные-члены во всех конструкторах.<br><br>Создавайте классы-одиночки с помощью закрытого конструктора.<br><br>Если сомневаетесь, выполняйте полное копирование, а не ограниченное.<br><br>Разумные причины создания класса:<br>-моделирование объектов реального мира;<br>-моделирование абстрактных объектов;<br>-снижение сложности;<br>-изоляция сложности;<br>-сокрытие деталей реализации;<br>-ограничение влияния изменений;<br>-сокрытие глобальных данных;<br>-упрощение передачи параметров в метод;<br>-создание центральныз точек управления;<br>-облегчение повторного использования кода;<br>-планирование создания семейства программ;<br>-упаковка родственных операций;<br>-выполнение специфического вида рефакторинга.<br><br>Классы, создавать которые не следует:<br>-избегайте создания классов, которые всё знают и всё могут;<br>-если класс имеет только данные, но не формы поведения, то это не класс;<br>-если класс имеет только формы поведения, но не даные, то это не класс.<br><br>Аспекты классов, зависящие от языка:<br>-поведение переопределённых конструкторов и деструкторов в дереве наследования;<br>-поведение конструкторов и деструкторов при обработке исключений;<br>-важность конструкторов по умолчанию (конструкторов без аргументов);<br>-время вызова деструктора или метода финализации;<br>-целесообразность переопределения встроенных операторов языка, в том числе операторов присваивания и сравнения;<br>-управление памятью при создании и уничтожении объектов или при их объявлении и выходе из области видимости.<br><br>В настоящее время использование классов - лучший способ достижения модульности.<br><br>Метод - это отдельная функция или процедура, выполняющая одну задачу.<br><br>Имя метода говорит о его роли.<br><br>Метод должен быть документирован, форматирован.<br><br>Входные переменные метода не изменяются.<br><br>Метод не работает с глобальными переменными.<br><br>Метод имеет одну чётко определённую цель, должен быть защищён от получения плохих данных, не использует магические числа; все параметры используются в методе, параметров у метода не более 7, параметры метода упорядочены.<br><br>Методы - самый эффективный способ уменьшения объёма и повышения быстродействия программ.<br><br>Разумные причины создания методов:<br>-снижение сложности;<br>-формирование понятной промежуточной абстракции;<br>-предотвращение дублирования кода;<br>-переопределить небольшой грамотно организованный метод легче, чем длинный и плохо спроектированный;<br>-сокрытие очерёдности действий;<br>-сокрытие неудобочитаемых операций;<br>-изоляция непортируемого кода;<br>-упрощение сложных булевых проверок;<br>-облегчение определения неэффективных фрагментов кода.<br><br>Один из главных ментальных барьеров, препятствующих созданию эффективных методов, - нежелание создавать простой метод для простой цели.<br><br>Высокая связность хуже низкой.<br><br>Функциональная связность - метод выполняет одну и только одну операцию.<br><br>Последовательная связность - метод содержит операции, которые обязательно выполняются в определённом порядке, используют данные предыдущих этапов и не формируют в целом единую функцию.<br><br>Коммуникационная связность - выполняемые в методе операции используют одни и те же данные и не связаны между собой иным образом.<br><br>Временная связность - когда операции объединяются в метод на том основании, что все они выполняются в один интервал времени.<br>Не выполнять в методе конкретные операции непосредственно, а вызывать для их выполнения другие методы.<br><br>Неприемлимые виды связности:<br>Процедурная связность - когда операции в методе выполняются в определённом порядке.<br>Поместить разные операции в разные методы.<br><br>Логическая связность - метод включает несколько операций, а выбор выполняемой операции осуществляется на основе передаваемого в метод управляющего флага.<br><br>Случайная связность - каких-либо ясных отношений между выполняемыми в методе операциями нет.<br><br>Стремиться создавать методы с функциональной связностью.<br><br>Советы по выбору удачных имён методов:<br>-описывайте всё, что метод выполняет (методы с побочными эффектами избавлять от побочных эффектов);<br>-избегайте невыразительных и неоднозначных глаголов (роль метода должна быть очевидной);<br>-не используйте для дифференциации имён методов исключительно номера;<br>-не ограничивайте длину имён методов искусственными правилами (оптимальная длина имени переменной равняется в среднем 9-15 символам, но имена методов обычно длиннее из-за их сложности);<br>-для именования функции используйте описание возвращаемого значения;<br>-для именования процедуры используйте выразительный глагол, дополняя его объектом (кроме ООП языков);<br>-дисциплинированно используйте антонимы (add/remove, begin/end, create/destroy, first/last, get/put, get/set, increment/decrement, insert/delete, lock/unlock, min/max, next/previous, old/new, open/close, show/hide, source/target, start/stop, up/down);<br>-определяйте конвенции именования часто используемых операций.<br><br>Код требует минимальных изменений, если методы состоят в среднем из 100-150 строк.<br><br>Предотвращение ошибок коммуникации между методами:<br>-передавайте параметры в порядке "входные значения - изменяемые значения - выходные значения";<br>-подумайте о создании собственных ключевых слов in и out;<br>-документируйте выраженные в интерфейсе предположения о параметрах;<br>Типы предположений:<br>-вид параметров: являются ли они исключительно входными, изменяемыми или исключительно выходными;<br>-единицы измерения (дюймы...);<br>-смыслы кодов статуса и ошибок, если для их представленияне используются перечисления;<br>-диапазоны допустимых значений;<br>-специфические значения, которые никогда не должны передаваться в метод;<br>-ограничивайте число параметров метода примерно семью;<br>-подумайте об определении конвенции именования входных, изменяемых и выходных параметров;<br>-передавайте в метод те переменные или объекты, которые нужны ему для поддержания абстракции интерфейса;<br>-сопряжение методов должно быть минимальным;<br>-используйте именованные параметры;<br>-убедитесь, что фактические (переданные в метод) параметры соответствуют формальным (объявленные в методе);<br>-проверяйте все возможные пути возврата значения из функции;<br>-инициализируйте возвращаемое значение значением по умолчанию в начале функции;<br>-не возвращайте ссылки или указатели на локальные данные (вместо ссылок - данные-члены).<br><br>Макросы:<br>-разрабатывая макрос, заключайте в скобки всё, что можно;<br>-заключайте макрос, включающий несколько команд, в фигурные скобки;<br>-не заменяйте методы макросами;<br>-называйте макросы, расширяющиеся в код подобно методам, так, чтобы при необходимости их можно было заменить методами;-теоретически встраивание методов может повысить быстродействие;<br>-не злоупотребляйте встраиваемыми методами.<br><br>Защита от неправильных входных данных:<br>-проверяйте все данные из внешних источников;<br>-проверяйте значения всех входных параметров метода;<br>-решите, как обрабатывать неправильные входные данные.<br><br>Утверждение - это код, используемый во время разработки, с помощью которого программа проверяет правильность своего выполнения (логическое выражение + сообщение).<br><br>Положения по применению утверждений:<br>-используйте процедуры обработки ошибок для ожидаемых событий и утверждения для событий, которые происходить не должны;<br>-старайтесь не помещать выполняемый код в утверждения;<br>-используйте утверждения для документирования и проверки предусловий и постусловий;<br><br>Предусловия - это соглашения, которые клиентский код, вызывающий метод или класс, обещает выполнить до вызова метода или создания экземпляра объекта.<br><br>Постусловия - это соглашения, которые метод или класс обещает выполнить при завершении своей работы.<br>-для большей устойчивости кода проверяйте утверждения, а затем всё равно обработайте возможные ошибки.<br><br>Способы обработки ошибок:<br>-вернуть нейтральное значение;<br>В больших, долгоживущих системах различные части могут разрабатываться несколькими проектировщиками 5-10 лет и более.<br>-заменить следующим корректным блоком данных;<br>-вернуть тот же результат, что и в предыдущий раз;<br>-подставить ближайшее допустимое значение;<br>-записать предупреждающее значение в файл;<br>-вернуть код ошибки;<br>-вызвать процедуру или объект-обработчик ошибок;<br>-показать сообщение об ошибке, где бы она ни случилась;<br>-обработать ошибку в месте возникновения наиболее подходящим способом;<br>-прекратить выполнение.<br><br>Корректность предполагает, что нельзя возвращать неточный результат; устойчивость требует всегда пытаться сделать что-то, что позволит программе продолжить работу.<br><br>Надо стараться реагировать на неправильные значения параметров одинаково во всей программе.<br><br>Предложения по исключениям:<br>-используйте исключения для оповещения других частей программы об ошибках, которые нельзя игнорировать;<br>-генерируйте исключения только для действительно исключительных ситуаций;<br>-не используйте исключения по мелочам (стараться обрабатывать ошибки локально);<br>-избегайте генерировать исключения в конструкторах и деструкторах, если только вы не перехватываете их позднее;<br>-генерируйте исключения на правильном уровне абстракции;<br>-вносите в описание исключения всю информацию о его причинах;<br>-избегайте пустых блоков catch;<br>-выясните, какие исключения генерирует используемая библиотека;<br>-рассмотрите вопрос о централизованном выводе информации об исключениях;<br>-стандартизуйте использование исключений в вашем проекте;<br>-рассмотрите альтернативы исключениям;<br>-преобразовывайте данные к нужному типу в момент ввода;<br>-методы с внешней стороны баррикады должны использовать обработчики ошибок, поскольку небезопасно делать любые предположения о данных; методы внутри баррикад должны использовать утверждения, так как данные, переданные им, считаются проверенными;<br>-промышленная версия: должна работать быстро, экономна с ресурсами, не позволяет пользователю делать опасные действия; отладочная версия: может работать медленно, может быть расточительной, может предоставлять дополнительные возможности без риска нарушить безопасность;<br>-внедрите поддержку отладки как можно раньше;<br>-исключительные случаи должны обрабатываться так, чтобы во время разработки они были очевидны, а в промышленном коде - позволяли продолжить работу;<br>-чем жестче требования во время разработки, тем проще эксплуатация;<br>-используйте встреонный препроцессор;<br>-используйте отладочные заглушки;<br>-оставьте код, который проверяет существенные ошибки;<br>-удалите код, проверяющий незначительные ошибки;<br>-удалите код, приводящий к прекращению работы программы;<br>-если на стадии разработки ваша программа обнаруживает ошибку, её надо сделать незаметнее, чтобы её могли исправить;-оставьте код, который позволяет аккуратно завершить работу программы;<br>-регламентируйте ошибки для отдела технической поддержки;<br>-убедитесь, что оставленные сообщения об ошибках дружелюбны (выводить телефон и адреса электронной почты, по которым можно о ней сообщить).<br><br>Обычно каждый метод тестируется при его создании.<br><br>Этапы конструирования классов:<br>1.Создание общей структуры класса;<br>2.Конструирование процедур класса;<br>3.Оценка и тестирование всего класса.<br><br>Действия по созданию метода:<br>1.Проектирование метода;<br>2.Проверка структуры;<br>3.Кодирование метода;<br>4.Пересмотр и тестирование кода.<br><br>Применение псевдокода:<br>-применяйте формулировки, в точности описывающие отдельные действия;<br>-избегайте синтаксических элементов языков программирования;<br>-описывайте назначение подхода, а не то, как этот подход нужно реализовать на выбранном языке программирования;<br>-пишите псевдокод на достаточно низком уровне, так чтобы код из него генерировался практически автоматически.<br><br>Сформулируйте задачу, решаемую методом, настолько детально, чтобы можно было переходить к созданию метода.<br><br>Затруднения в выборе имени метода могут свидетельствовать о том, что его назначение не совсем понятно.<br><br>Метод должен иметь понятное, недвусмысленное имя.<br><br>В процессе написания метода думайте о том, как вы будете его тестировать.<br><br>Исследуйте функциональность, представляемую стандартными библиотеками.<br>Не тратьте время на реализацию готового алгоритма, по которому написана кандидатская диссертация.<br><br>Подумайте обо всём плохом, что может случиться с вашим методом.<br><br>Не теряйте времени на вылизывание отдельных методов, пока не выяснится, что это необходимо.<br><br>Если доступные библиотеки не предоставляют нужной функциональности, имеет смысл исследовать литературу с описанием алгоритмов.<br><br>Общая идея: раз за разом проходиться по псевдокоду, пока каждое его предложение не станет настолько простым, что под ним можно будет вставить строку программы, а псевдокод оставить в качестве документации.<br><br>Этапы кодирования метода:<br>1.Напишите объявление метода;<br>2.Напишите первый и последний операторы, а псевдокод превратите в комментарии верхнего уровня;<br>3.Добавьте код после каждого комментария;<br>4.Проверьте код;<br>5.Исправьте неточности.<br><br>Длина абзаца кода, как и длина абзаца литературного текста, зависит от высказываемой мысли, а его качество - от понимания автором сути.<br><br>Проверьте, не нужна ли дальнейшая декомпозиция кода.<br><br>Умозрительно проверьте ошибки в методе.<br><br>Только около 5% всех ошибоксвязано с аппаратурой, компиляторам или ОС.<br><br>Если вы не знаете, почему это работает, вероятно, оно и не работает на самом деле.<br><br>Не спешите и не компилируйте программу, пока не будете уверены, что она верна.<br><br>Установите наивысший уровень предупреждений компилятора.<br><br>Применяйте проверяющие средства.<br><br>Убедитесь, что каждая строка выполняется так, как вы ожидаете.<br><br>Леса - код, поддерживающий методы при тестировании и не включаемый в конечный продукт.<br><br>Полное перепроектирование нестабильного метода полностью оправданно.<br><br>Если качество метода неудовлетворительное, вернитесь к псевдокоду.<br><br>Рекурсивное применение псевдокода - разбиение метода на более мелкие при необходимости.<br><br>Комментарии должны быть адекватными и полезными.<br><br>Неявное объявление переменных - одна из самых опасных возможностей языка.<br><br>Объявляйте все переменные.<br><br>Отключите неявные объявления.<br><br>Используйте конвенции именования.<br><br>Проверяйте имена переменных.<br><br>Инициализируйте каждую переменную при её объявлении.<br><br>Инициализируйте каждую переменную там, где она используется в первый раз (если нельзя инициализировать при объявлении).<br><br>В идеальном случае сразу объявляйте и определяйте каждую переменную непосредственно перед первым обращением к ней.<br><br>Объявляйте переменные по мере возможности как const.<br><br>Не забывайте обнулять счётчики и аккумуляторы.<br><br>Специализируйте данные-члены класса в его конструкторе.<br><br>Проверяйте необходимость повторной инициализации.<br><br>Область видимости - фрагмент программы, в котором переменная известна и может быть использована.<br><br>Локализуйте обращения к переменным (уменьшать интервал).<br><br>Делайте время жизни переменных как можно короче (измеряется в строках).<br><br>Избегайте глобальных переменных из-за большого времени жизни.<br><br>Инициализируйте переменные, используемые в цикле, непосредственно перед циклом, а не в начале метода, содержащего цикл.<br><br>Не присваивайте переменной значение вплоть до его использования.<br><br>Группируйте связанные команды.<br><br>Разбивайте группы связанных команд на отдельные методы.<br><br>Начинайте с самой ограниченной области видимости и расширяйте её только при необходимости.<br><br>Локальная область видимости способствует интеллектуальной управляемости.<br><br>Персистентность характеризует длительность существования данных.<br><br>Время связывания - момент, когда переменная и её значение связываются вместе.<br><br>Так как эффективность программирования зависит от минимизации сложности, опытный программист будет обеспечивать такой уровень гибкости, какой нужен для удовлетворения требований, но не более того.<br><br>Последовательные данные соответствуют последовательности команд.<br><br>Селективные данные соответствуют операторам if и case.<br><br>Итеративные данные соответствуют циклам.<br><br>Используйте каждую переменную только с одной целью.<br><br>Избегайте переменных, имеющих скрытый смысл (избегайте гибридного сопряжения).<br><br>Убеждайтесь в том, что используются все объявленные переменные.<br><br>Имя переменной должно полно и точно описывать сущность, представляемую переменной.<br><br>Имена должны быть максимально конкретны.<br><br>Имя переменной описывает проблему, а не её решение.<br><br>Отладка программы требует меньше усилий, если имена переменных состоят в среднем из 10-16 символов.<br><br>Более длинные имена лучше присваивать редко используемым или глобальным переменным, а более короткие - локальным переменным или переменным, вызываемым в циклах.<br><br>Дополняйте имена, относящиеся к глобальному пространству имён, спецификаторами.<br><br>Имена вычисляемых значений дополнять спецификатором из Total, Sum, Average, Max, Min, Record, String, Pointer в конце имени.<br><br>В именах лучше использовать антонимы: begin/end, first/last, locked/unlocked, min/max, next/previous, old/new, opened/closed, visible/invisible, source/target, source/destination, up/down.<br><br>Индексы циклов - i, j, k.<br><br>Если код часто изменяется, модернизируется, копируется, лучше делать осмысленные имена индексов.<br><br>Имя флага не должно включать фрагмент flag, потому что он ничего не говорит о сути флага.<br><br>Значения флагов лучше сравнивать со значениями перечислений, именованных констант или глобальных переменных, выступающих в роли именованных констант.<br><br>Использование временных переменных говорит о том, что программист ещё не полностью понял проблему.<br><br>Временным переменным давать точное описание.<br><br>Типичные имена булевых переменных: признак завершения - done, признак ошибки - error, признак обнаружения - found, признак успешного завершения - ok или success.<br><br>Присваивайте булевым переменным имена, подразумевающие значение true или false.<br><br>Используйте утвердительные имена булевых переменных.<br><br>Имя константы должно характеризовать абстрактную сущность, представляемую константой, а не конкретное значение.<br><br>Обязательно используйте конвенции именования, так как это всегда выгодно.<br><br>Советы по созданию конвенции:<br><br>Проведите различие между именами переменных и именами методов.<br><br>Проведите различие между классами и объектами.<br><br>Идентифицируйте глобальные переменные, переменные-члены, определения типов, именованные константы, элементы перечислений, неизменяемые параметры.<br><br>Формируйте имена так, чтобы их было легко читать.<br><br>Сокращение имён стало пережитком.<br><br>Не сокращайте слова только на один символ.<br><br>Всегда используйте один и тот же вариант сокращения.<br><br>Сокращайте имена так, чтобы их можно было произнести.<br><br>Избегайте комбинаций, допускающих неверное прочтение или произношение имён.<br><br>Обращайтесь к словарю для разрешения конфликтов имён.<br><br>Документируйте очень короткие имена прямо в коде при помощи таблиц.<br><br>Указывайте все сокращения в проектном документе "Стандартные аббревиатуры".<br><br>Помните, что имена создаются в первую очередь для программистов, читающих код.<br><br>Избегайте обманчивых имён или аббревиатур.<br><br>Избегайте имён, имеющих похожие значения.<br><br>Избегайте переменных, имеющих разную суть, но похожие имена.<br><br>Избегайте имён, имеющих похожее звучание, таких как wrap и rap.<br><br>Избегайте имён, включающих цифры.<br><br>Избегайте орфографических ошибок.<br><br>Избегайте слов, при написании которых люди часто допускают ошибки.<br><br>Проводите различие между именами не только по регистру букв.<br><br>Избегайте смешения естественных языков.<br><br>Избегайте имен стандартных типов, переменных и методов.<br><br>Не используйте имена, которые совершенно не связаны с тем, что представляют переменные.<br><br>Избегайте имён, содержащих символы, которые можно спутать с другими символами.<br><br>Избегайте "магических чисел".<br><br>Используйте в программе как константы только 0 и 1, а любые другие числа определите как литералы с понятными именами.<br><br>Пишите код, предупреждающий появление ошибки деления на 0.<br><br>Выполняйте преобразования типов понятно.<br><br>Избегайте сравнений разных типов.<br><br>Обращайте внимание на предупреждения вашего компилятора.<br><br>Проверяйте целочисленность операций деления.<br><br>Проверяйте переполнение целых чисел.<br><br>Проверяйте на переполнение промежуточные результаты.<br><br>Избегайте сложения и вычитания слишком разных по размеру чисел с плавающей запятой.<br><br>Избегайте сравнений на равенство чисел с плавающей запятой.<br><br>Предупреждайте ошибки округления.<br><br>Проверяйте поддержку специальных типов данных в языке и дополнительных библиотеках.<br><br>Избегайте магических символов и строк.<br><br>Следите за ошибками завышения/занижения на единицу индексов.<br><br>Узнайте как ваш язык и система поддерживают Unicode.<br><br>Разработайте стратегию интернационализации/локализации в ранний период жизни программы.<br><br>Если вам известно, что нужно поддерживать только один алфавит, рассмотрите вариант использования набора символов ISO8859.<br><br>Если вам необходимо поддерживать несколько языков, используйте Unicode.<br><br>Выберите целостную стратегию преобразования строковых типов.<br><br>Используйте логические переменные для документирования программы.<br><br>Используйте логические переменные для упрощения сложных условий.<br><br>Используйте перечислимые типы для читабельности.<br><br>Используйте перечислимые типы для надёжности.<br><br>Используйте перечислимые типы для модифицируемости.<br><br>Используйте перечислимые типы как альтернативу логическим переменным.<br><br>Проверяйте некорректные значения в case с перечислимым типом.<br><br>Настройте первый и последний элемент перечислимого типа для использования в качестве границ циклов.<br><br>Зарезервируйте первый элемент перечислимого типа как недопустимый.<br><br>Точно укажите в стандартах кодирования для проекта, как должны использоваться первый и последний элементы, и неукоснительно придерживайтесь этого.<br><br>Помните о подводных камнях в присваивании явных значений элементам перечисления.<br><br>Если в языке нет перечислимых типов, их можно имитировать, используя глобальные переменные или классы.<br><br>Используйте именованные константы в объявлениях данных.<br><br>Избегайте литеральных значений, даже "безопасных".<br><br>Если в языке их нет, имитируйте именованные константы с помощью переменных или классов правильной области видимости.<br><br>Не используйте для представления одной сущности именованные константы в одном месте и литералы в другом.<br><br>Убедитесь, что все значения индексов массива не выходят за его границы.<br><br>Обдумайте применение контейнеров вместо массивов или рассматривайте массивы как последовательные структуры (наборов, стеков, очередей и т.п.).<br><br>Проверяйте конечные точки массивов.<br><br>В многомерном массиве убедитесь, что его индексы используются в правильном порядке.<br><br>Остерегайтесь пересечения индексов - перемены мест индексов.<br><br>Принципы создания собственных типов:<br><br>Создавайте типы с именами, отражающими их функциональность.<br><br>Преимущество создания собственных типов в появлении слоя, скрывающего язык.<br><br>Избегайте предопределённых типов.<br><br>Не переопределяйте предопределённые типы.<br><br>Определите подстановки для переносимости.<br><br>Рассмотрите вопрос создания класса вместо использования typedef.<br><br>Используйте структуры для упрощения списка параметров.<br><br>Между методами должна передаваться только та информация, которую необходимо знать.<br><br>Используйте структуры для упрощения сопровождения.<br><br>Используйте технологию, не основанную на указателях.<br><br>Избегайте преднамеренных изменений глобальных данных.<br><br>Глобальные данные должны сохранять свои значения, даже если будет запущено несколько копий программы.<br><br>Глобальные данные затрудняют повторное использование кода.<br><br>Глобальные данные приводят к неопределённому порядку инициализации.<br><br>Глобальные данные привносят нарушение модульности и интеллектуальной управляемости.<br><br>Глобальные данные подходят для хранения глобальных значений.<br><br>Глобальные данные подходят для эмуляции именованных констант, если они не поддерживаются.<br><br>Глобальные данные подходят для эмуляции перечислимых типов.<br><br>Глобальные данные можно использовать для оптимизации обращений к часто используемым данным.<br><br>Применение глобальных переменных позволяет избежать бродячие данные.<br><br>Начните с объявления всех переменных локальными и делайте их глобальными только по необходимости.<br><br>Различайте глобальные переменные и переменные-члены класса.<br><br>Используйте методы доступа.<br><br>Требуйте, чтобы в свойствах весь код обращался к данным через методы доступа.<br><br>Не валите все глобальные данные в одну кучу.<br><br>Управляйте доступом к глобальным переменным с помощью блокировок.<br><br>Встройте уровень абстракции в методы доступа (не используйте структуры напрямую).<br><br>Выполняйте доступ к данным на одном и том же уровне абстракции.<br><br>Разработайте соглашения по именованию, которые сделают глобальные переменные очевидными.<br><br>Создайте хорошо аннотированный список всех глобальных переменных.<br><br>Не храните промежуточных результатов в глобальных переменных.<br><br>Не считайте, что вы не использутете глобальные переменные, поместив все данные в чудовищный объект и передавая его всюду.<br><br>Операторы:<br><br>Факт зависимости одного выражения от другого должен быть понятен из имен методов.<br><br>Организуйте код так, чтобы зависимости между операторами были очевидными.<br><br>Называйте методы так, чтобы зависимости были очевидными.<br><br>Используйте параметры методов, чтобы сделать зависимости очевидными.<br><br>Документируйте неявные зависимости с помощью комментариев.<br><br>Проверяйте зависимости с помощью утверждений или кода обработки ошибок.<br><br>Располагайте взаимосвязанные действия вместе.<br><br>При написании if-выражений:<br><br>Сначала напишите код номинального хода алгоритма, затем опишите исключительные ситуации.<br><br>Убедитесь, что при сравнении на равенство ветвление корректно.<br><br>Размещайте нормальный вариант после if, а не после else.<br><br>Размещайте осмысленные выражения после оператора if.<br><br>Рассмотрите вопрос использования блока else (в 50-80% случаев использования if следовало применить и else).<br><br>Проверяйте корректность выражения else.<br><br>Проверяйте возможную перестановку блоков if и else.<br><br>Упрощайте сложные проверки с помощью вызовов логических функций.<br><br>Размещайте наиболее вероятные варианты раньше остальных.<br><br>Убедитесь, что учтены все варианты.<br><br>Замените последовательности if-then-else другими конструкциями, которые поддерживает ваш язык программирования.<br><br>В case:<br>-упорядочивайте варианты case по алфавиту или численно;<br>-поместите правильный вариант case первым;<br>-отсортируйте варианты по частоте.<br><br>Сделайте обработку каждого варианта case простой.<br><br>Не конструируйте искусственные переменные с целью получить возможность использовать оператор case.<br><br>Используйте вариант по умолчанию только для обработки настоящих значений по умолчанию.<br><br>Используйте вариант по умолчанию для выявления ошибок.<br><br>Старайтесь не писать код, проваливающийся сквозь блоки оператора case.<br><br>Минимизируйте число факторов, влияющих на цикл.<br><br>Вынесите за пределы цикла всё управление, какое только можно.<br><br>Размещайте вход в цикл только в одном месте.<br><br>Размещайте инициализационный код непосредственно перед циклом.<br><br>Используйте while(true) для бесконечных циклов.<br><br>Предпочитайте циклы for, если они применимы.<br><br>Не используйте цикл for, если цикл while подходит больше.<br><br>Используйте{и}для обрамления выражений в цикле.<br><br>Избегайте пустых циклов.<br><br>Располагайте служебные операции либо в начале, либо в конце цикла.<br><br>Заставьте каждый цикл выполнять только одну функцию.<br><br>При завершении цикла убедитесь, что выполнение цикла закончилось.<br><br>Сделайте условие завершения цикла очевидным.<br><br>Не играйте с индексом цикла for для завершения цикла.<br><br>Избегайте писать код, зависящий от последнего значения индекса цикла.<br><br>Рассмотрите использование счетчиков безопасности, чтобы определить, не слишком ли много раз выполняется цикл.<br><br>Рассмотрите использование операторов break вместо логических флагов в цикле while.<br><br>Остерегайтесь цикла с множеством операторов break, разбросанных по всему коду.<br><br>Используйте continue для проверок в начале цикла.<br><br>Используйте структуру break с метками, если ваш язык её поддерживает.<br><br>Используйте операторы break и continue очень осторожно.<br><br>Используйте порядковые или перечислимые типы для границ массивов и циклов.<br><br>Используйте смысловые имена переменных, чтобы сделать вложенные циклы читабельными.<br><br>Используйте смысловые имена во избежание пересечения индексов.<br><br>Ограничивайте видимость переменных-индексов цикла самим циклом.<br><br>Делайте циклы достаточно короткими, чтобы их можно было увидеть сразу целиком.<br><br>Ограничивайте вложенность тремя уровнями.<br><br>Выделяйте внутреннюю часть длинных циклов в отдельные методы.<br><br>Делайте длинные циклы особенно ясными.<br><br>Простое создание цикла - изнутри наружу.<br><br>Используйте return, если это повышает читабельность.<br><br>Упрощайте сложную обработку ошибок с помощью сторожевых операторов (досрочного return).<br><br>Минимизируйте числов возвратов из каждого метода.<br><br>Убедитесь, что рекурсия остановится.<br><br>Предотвращайте бесконечную рекурсию с помощью счетчиков безопасности.<br><br>Ограничьте рекурсию одним методом.<br><br>Следите за стеком при использовании рекурсии.<br><br>Не используйте рекурсию для факториалов и чисел Фибоначчи.<br><br>Лучше обходиться без goto.<br><br>Код с goto переписать с помощью вложенных if.<br><br>Код с goto переписать с использованием статусной переменной.<br><br>Табличный метод - это схема, позволяющая искать информацию в таблице, а не использовать для этого логические выражения.<br><br>Таблица с прямым доступом позволяет обращаться изначально напрямую (есть ещё индексированный и ступенчатый доступ).<br><br>Используйте неявное сравнение логических величин с true или false.<br><br>Разбивайте сложные проверки на части с помощью новых логических переменных.<br><br>Размещайте сложные выражения в логических функциях.<br><br>Используйте таблицы решений для замены сложных условий.<br><br>В операторах if заменяйте негативные выражения позитивными, меняя местами блоки if и else.<br><br>Применяйте теоремы Деморгана для упрощения логических проверок с отрицаниями.<br><br>Используйте скобки для явного задания порядка вычисления.<br><br>Используйте простой метод подсчета для проверки симметричности скобок ( ( - +1, ) - -1).<br><br>Заключайте в скобки логическое выражение целиком.<br><br>Организуйте числовые условия так, чтобы они соответствовали порядку точек на числовой прямой.<br><br>Неявно сравнивайте логические переменные.<br><br>Сравнивайте числа с 0.<br><br>Сравнивайте указатели с null.<br><br>В C-подобных языках помещайте константы с левой стороны сравнений.<br><br>Учитывайте разницу между a==b и a.equals(b) (Java).<br><br>Пишите обе скобки блока одновременно.<br><br>Всегда используйте скобки для условных операторов (для пояснения).<br><br>Привлекайте внимание к нужным выражениям.<br><br>Создайте для пустых выражений макрос препроцессора или встроенную функцию DoNothing().<br><br>Подумайте, не будет ли код яснее с непустым телом цикла.<br><br>Не используйте больше 3 уровней вложенности if.<br><br>Упростите вложенные if с помощью повторной проверки части условия.<br><br>Упростите вложенные if с помощью блока с выходом do{...break...}while(false);.<br><br>Преобразуйте вложенные if в набор if-then-else.<br><br>Преобразуйте вложенные if в оператр case.<br><br>Факторизуйте глубоковложенный код в отдельный метод.<br><br>Используйте более объекто-ориентированный подход.<br><br>Перепроектируйте глубоковложенный код.<br><br>Основной тезис структурного программирования: любая управляющая логика программы может быть реализована с помощью последовательности, выбора и итерации.<br><br>Методики поиска дефектов лучше применять в комбинации.<br><br>Обзор кода эффективнее тестирования.<br><br>Ошибки в требованиях или архитектуре обычно имеют более широкие следствия, чем ошибки конструирования.<br><br>Повышение качества системы снижает расходы на ее разработку.<br><br>Средняя производительность труда программистов эквивалентна 10-50 строкам кода на одного человека в день.<br><br>Устранение дефектов - самый дорогой и длительный этап разработки ПО.<br><br>На создание ПО без дефектов не всегда уходит больше времени, чем на написание ПО с дефектами.<br><br>Разработчики допускают в среднем от 1 до 3 дефектов в час при проектировании и от 5 до 8 дефектов в час при кодировании.<br><br>Каждый час инспекции кода предотвращает около 100 часов аналогичной работы (тестирования и исправления дефектов).<br><br>Поддерживайте парное программирование стандартами кодирования.<br><br>Не позволяйте парному программированию превратиться в наблюдение.<br><br>Не используйте парное программирование для реализации простых фрагментов.<br><br>Регулярно меняйте состав пар и назначаемые парам задачи.<br><br>Объединяйте в пару людей, предпочитающих одинаковый темп работы.<br><br>Убедитесь, что оба члена пары видят экран.<br><br>Не объединяйте в пары людей, которые не нравятся друг другу.<br><br>Не составляйте пару из людей, которые ранее не программировали в паре.<br><br>Назначьте лидера группы.<br><br>Инспектор может проанализировать за час около 500 строк.<br><br>Тестирование - самая популярная методика повышения качества.<br><br>Тестирование - средство обнаружения ошибок.<br><br>Отладка - средство поиска и устранения причин уже обнаруженных ошибок.<br><br>Тестированию, выполняемому разработчиками, следует посвящать от 8% до 25% общего времени работы над проектом.<br><br>Искусство тестирования заключается в выборе тестов, способных обеспечить максимальную вероятность обнаружения ошибок.<br><br>Структурированное базисное тестирование - протестировать каждый оператор программы хотя бы раз.<br><br>Проверяйте код тестов.<br><br>Планируйте тестирование программы так же, как и ее разработку.<br><br>Храните тесты.<br><br>Встраивайте блочные тесты в среду тестирования.<br><br>Используйте генераторы случайных данных.<br><br>Изучите программу, над которой работаете.<br><br>Изучите собственные ошибки.<br><br>Изучите качество своего кода с точки зрения кого-то, кому придется читать его.<br><br>Изучите используемые способы решения проблем.<br><br>Изучите используемые способы исправления дефектов.<br><br>Формулируя гипотезу, используйте все имеющиеся данные.<br><br>Детализируйте тесты, приводящие к ошибке.<br><br>Проверяйте код при помощи блочных тестов.<br><br>Используйте разные инструменты.<br><br>Воспроизведите ошибку несколькими способами.<br><br>Генерируйте больше данных для формулирования большего числа гипотез.<br><br>Используйте "мозговой штурм" для построения нескольких гипотез.<br><br>Составьте список подходов, которые стоит попробовать.<br><br>Сохраните подозрительную область кода.<br><br>С подозрением относитесь к классам, которые содержали дефекты ранее.<br><br>Проверьте код, который был изменён недавно.<br><br>Расширьте подозрительный фрагмент кода.<br><br>Выполняйте интеграцию инкрементно.<br><br>Проверяйте наличие распространённых дефектов.<br><br>Обсудите проблему с кем-то другим.<br><br>Отдохните от проблемы.<br><br>Установите лимит времени для быстрой и грязной отладки.<br><br>Составьте список методик грубой силы.<br><br>Не полагайтесь на номера строк в сообщениях компилятора.<br><br>Не доверяйте сообщениям компилятора.<br><br>Не доверяйте второму сообщению компилятора.<br><br>Разделяйте программу на части.<br><br>Грамотно ищите неверно размещённые комментарии и кавычки.<br><br>Прежде чем браться за решение проблемы, поймите её.<br><br>Подтвердите диагноз проблемы.<br><br>Расслабьтесь (не поддавайтесь соблазну сэкономить время).<br><br>Сохраняйте первоначальный исходный код.<br><br>Устраняйте проблему, а не её симптомы.<br><br>Изменяйте код только при наличии веских оснований.<br><br>Вносите в код по одному изменению.<br><br>Добавляйте в набор тестов блочные тесты, приводящие к проявлению имеющихся дефектов.<br><br>Поищите похожие дефекты.<br><br>Выбирайте во время конструирования имена, ясно отличающиеся от других имён.<br><br>Используйте утилиты сравнения исходного кода.<br><br>Задайте в компиляторе максимально строгий уровень диагностики и устраняйте все ошибки и предупреждения.<br><br>Рассматривайте предупреждения как ошибки.<br><br>Стандартизуйте параметры компилятора в масштабе всего проекта.<br><br>Используйте утилиты расширенной проверки синтаксиса и логики.<br><br>Профилируйте код для поиска ошибок.<br><br>Даже в хорошо управляемых проектах требования изменяются на 1-4% в месяц.<br><br>Современные подходы снижают предсказуемость кодирования.<br><br>Факторинг - максимальная декомпозиция программы на составляющие части.<br><br>Причины выполнения рефакторинга:<br><br>Код повторяется.<br><br>Метод слишком велик.<br><br>Цикл слишком велик или слишком глубоко вложен в другие циклы.<br><br>Класс имеет плохую связность.<br><br>Интерфейс класса не формирует согласованную абстракцию.<br><br>Метод принимает слишком много параметров.<br><br>Отдельные части класса изменяются независимо от других частей.<br><br>При изменении программы требуется параллельно изменять несколько классов.<br><br>Вам приходится параллельно изменять несколько иерархий наследования.<br><br>Вам приходится параллельно изменять несколько блоков case.<br><br>Родственные элементы данных, используемые вместе, не организованы в классы.<br><br>Метод использует больше элементов другого класса, чем своего собственного.<br><br>Элементарный тип данных перегружен.<br><br>Класс имеет слишком ограниченную функциональность.<br><br>По цепи методов передаются бродячие данные.<br><br>Объект-посредник ничего не делает.<br><br>Один класс слишком много знает о другом классе.<br><br>Метод имеет неудачное имя.<br><br>Данные-члены сделаны открытыми.<br><br>Подкласс использует только малую долю методов своих предков.<br><br>Сложный код объясняется при помощи комментариев.<br><br>Код содержит глобальные переменные.<br><br>Перед вызовом метода выполняется подготовительный код (после вызова метода выполняется код уборки).<br><br>Программа содержит код, который может когда-нибудь понадобиться.<br><br>Рефакторинги на уровне данных:<br><br>Замена магического числа на именованную константу.<br><br>Присвоение переменной более ясного или информативного имени.<br><br>Встраивание выражения в код.<br><br>Замена выражения на вызов метода.<br><br>Введение промежуточной переменной.<br><br>Преобразование многоцелевой переменной в несколько одноцелевых переменных.<br><br>Использование локальной переменной вместо параметра.<br><br>Преобразование элементарного типа данных в класс.<br><br>Преобразование набора кодов в класс или перечисление.<br><br>Преобразование набора кодов в класс, имеющий производные классы.<br><br>Преобразование массива в класс.<br><br>Инкапсуляция набора.<br><br>Замена традиционной записи на класс данных.<br><br>Рефакторинги на уровне отдельных операторов:<br><br>Декомпозиция логического выражения.<br><br>Вынесение сложного логического выражения в грамотно названную булеву функцию.<br><br>Консолидация фрагментов, повторяющихся в разнах частях условного оператора.<br><br>Использование оператора break или return вместо управляющей переменной цикла.<br><br>Возврат из метода сразу после получения ответа вместо установки возвращаемого значения внутри вложенных операторов if-then-else.<br><br>Замена условных операторов (обычно многочисленных блоков case) на вызов полиморфного метода.<br><br>Создание и использование "пустых" объектов вместо того, чтобы проверять, равно ли значение null.<br><br>Извлечение метода из другого метода.<br><br>Встраивание кода метода.<br><br>Преобразование объёмного метода в класс.<br><br>Замена сложного алгоритма на простой.<br><br>Добавление параметра.<br><br>Удаление параметра.<br><br>Отделение операций запроса данных от операций изменения данных.<br><br>Объединение похожих методов путём их параметризации.<br><br>Разделение метода, поведение которого зависит от полученных параметров.<br><br>Передача в метод целого объекта вместо отдельных полей.<br><br>Передача в метод отдельных полей вместо целого объекта.<br><br>Инкапсуляция нисходящего приведения типов.<br><br>Рефакторинги реализации классов:<br><br>Замена объектов-значений на объекты-ссылки.<br><br>Замена объектов-ссылок на объекты-значения.<br><br>Замена виртуальных методов на инициализацию данных.<br><br>Изменение положения методов-членов или данных-членов в иерархии наследования.<br><br>Перемещение специализированного кода в подкласс.<br><br>Объединение похожего кода и его перемещение в суперкласс.<br><br>Рефакторинги интерфейсов классов:<br><br>Перемещение метода в другой класс.<br><br>Разделение одного класса на несколько.<br><br>Удаление класса.<br><br>Сокрытие делегата.<br><br>Удаление посредника.<br><br>Замена наследования на делегирование.<br><br>Замена делегирования на наследование.<br><br>Создание внешнего метода.<br><br>Создание класса-расширения.<br><br>Инкапсуляция открытой переменной-члена.<br><br>Удаление методов установки значений неизменяемых полей.<br><br>Сокрытие методов, которые не следует вызывать извне класса.<br><br>Инкапсуляция неиспользуемых методов.<br><br>Объединение суперкласса и подкласса, имеющих очень похожую реализацию.<br><br>Рефакторинг на уровне системы:<br><br>Создание эталонного источника данных, которые вы не можете контролировать.<br><br>Изменение однонаправленной связи между классами на двунаправленную.<br><br>Изменение двунаправленной связи между классами на однонаправленную.<br><br>Предоставление фабричного метода вместо простого конструктора.<br><br>Замена кодов ошибок на исключения или наоборот.<br><br>Сохраняйте первоначальный код.<br><br>Стремитесь ограничить объем отдельных видов рефакторинга.<br><br>Выполняйте отдельные виды рефакторинга по одному за раз.<br><br>Составьте список действий, которые вы собираетесь предпринять.<br><br>Составьте и поддерживайте список видов рефакторинга, которые следует выполнить позже.<br><br>Часто создавайте контрольные точки.<br><br>Используйте предупреждения компилятора.<br><br>Выполняйте регрессивное тестирование.<br><br>Создавайте дополнительные тесты.<br><br>Выполняйте обзоры изменений.<br><br>Изменяйте подход в зависимости от рискованности рефакторинга.<br><br>Не рассматривайте рефакторинг как оправдание написания плохого кода с намерением исправить его позднее.<br><br>Не рассматривайте рефакторинг как способ, позволяющий избежать переписывания кода.<br><br>Тратьте время на 20% видов рефакторинга, обеспечивающих 80% выгоды.<br><br>Выполняйте рефакторинг при создании новых методов.<br><br>Выполняйте рефакторинги при создании новых классов.<br><br>Выполняйте рефакторинг при исправлении дефектов.<br><br>Выполняйте рефакторинг модулей, подверженных ошибкам.<br><br>Выполняйте рефакторинг сложных модулей.<br><br>При сопровождении программы улучшайте фрагменты, к которым прикасаетесь.<br><br>Определите интерфейс между аккуратным и безобразным кодом и переместите безобразный код на другую сторону этого интерфейса.<br><br>Простое задание явных целей повышает вероятность их достижения.<br><br>На 20% методов программы приходятся 80% времени её выполнения.<br><br>Сокращение числа строк высокоуровневого кода не повышает быстродействие и не уменьшает объем итогового машинного кода.<br><br>Без измерения производительности вы никак не сможете точно узнать, помогли ваши изменения программе или навредили.<br><br>Методики, повышающие производительность в одной среде, могут снижать ее в других.<br><br>До создания полностью работоспособной программы найти узкие места в коде почти невозможно.<br><br>Концентрация на производительности во время первоначальной разработки отвлекает от достижения других целей.<br><br>Корректность важнее быстродействия.<br><br>Частые причины снижения эффективности:<br><br>Операции ввода/вывода.<br><br>Замещение страниц памяти.<br><br>Системные вызовы.<br><br>Интерпретируемые языки.<br><br>Ошибки.<br><br>Повышение быстродействия исходит из замены дорогой операции на более дешевую.<br><br>Главная проблема оптимизации кода: результат любого отдельного вида оптимизации непредсказуем.<br><br>Замыкание цикла - принятие решения внутри цикла при каждой его интерации.<br><br>Разомкнутый цикл - принятие решения вне цикла.<br><br>Если два цикла работают с одним набором элементов, можно выполнить их объединение.<br><br>После частичного развёртывания цикла при каждой его итерации обрабатывается не один случай, а два и более.<br><br>Вкладывайте более ресурсоемкий цикл в менее ресурсоемкий.<br><br>Минимизируйте число обращений к массивам.<br><br>Даже слепые белки иногда наталкиваются на орехи.<br><br>Назначьте двух человек на каждую часть проекта.<br><br>Рецензируйте каждую строку кода.<br><br>Введите процедуру подписания кода.<br><br>Распространяйте для ознакомления хорошие примеры кода.<br><br>Подчеркивайте, что код - это общее имущество.<br><br>Награждайте за хороший код.<br><br>"Я должен быть в состоянии прочесть и понять любой код, написанный в проекте."<br><br>Следуйте систематической процедуре контроля изменений.<br><br>Обрабатывайте затраты на каждое изменение.<br><br>Оценивайте затраты на каждое изменение.<br><br>Относитесь с подозрением к изменениям большого объема.<br><br>Учредите комитет контроля изменений.<br><br>Соблюдайте бюрократические процедуры, но не позволяйте страху перед бюрократией препятствовать эффективному контролю изменений.<br><br>Оценка графика контруирования:<br><br>Определите цели.<br><br>Выделите время для оценки.<br><br>Выясните требования к программе.<br><br>Делайте оценки на низком уровне детализации.<br><br>Используйте несколько способов оценки и сравнивайте полученные результаты.<br><br>Периодически делайте повторную оценку.<br><br>Храните сведения об опыте проектов в вашей организации и используйте их для оценки времени, необходимого будущим проектам.<br><br>Наибольшее влияние на график программного проекта оказывает размер создаваемой программы.<br><br>Если вы отстаете:<br><br>Надеяться, что вы сможете наверстать упущенное.<br><br>Задержки и отклонения от графика обычно увеличиваются по мере приближения к концу проекта.<br><br>Увеличить команду (если есть независимые задачи).<br><br>Сократить проект.<br><br>При первоначальном планировании продукта разделите его возможности на категории "должны быть", "хорошо бы сделать", "необязательные".<br><br>Причины, по которым стоит проводить измерение проекта:<br><br>Для любого атрибута проекта существует возможность его измерения, что в любом случае не означает отказа от его измерения.<br><br>Отдавайте себе отчет о побочных эффектах измерения.<br><br>Возражать против измерений означает утверждать, что лучше не знать о том, что на самом деле происходит.<br><br>80% работы выполняют 20% сотрудников.<br><br>Если вы хотите контролировать стиль программиста:<br><br>Вы вторгаетесь в область, требующую деликатного обращения.<br><br>Из уважения к теме используйте термины "предложения" и "советы".<br><br>Старайтесь обходить стороной спорные вопросы, предпочитая давать явные поручения.<br><br>Предложите программистам выработать собственные стандарты.<br><br>Просвещайте менеджеров.<br><br>Писать и тестировать маленькие участки программы, а затем комбинировать эти кусочки друг с другом по одному.<br><br>Преимущества этой инкрементной итерации:<br><br>Ошибки можно легко обнаружить.<br><br>В таком проекте система раньше становится работоспособной.<br><br>Вы получаете улучшенный мониторинг состояния.<br><br>Вы улучшите отношения с заказчиком.<br><br>Системные модули тестируются гораздо полнее.<br><br>Вы можете создать систему за более короткое время.<br><br>При нисходящей интеграции вы создаете те классы, которые находятся на вершине иерархии, первыми, а те, что внизу, - последними.<br><br>Систему можно разбить на вертикальные слои.<br><br>При восходящей интеграции вы пишете и интегрируете сначала классы, находящиеся в низу иерархии.<br><br>При риск-ориентированной интеграции вы решаете, какие части системы будут самыми трудными, и реализуете их первыми.<br><br>Ещё один подход - интеграция одной функции в каждый момент времени.<br><br>Создавайте сборку ежедневно.<br><br>Проверяйте правильность сборок.<br><br>Выполняйте дымовые тесты ежедневно.<br><br>Поддерживайте актуальность дымового теста.<br><br>Автоматизируйте ежедневную сборку и дымовой тест.<br><br>Организуйте группу, отвечающую за сборки.<br><br>Вносите исправления в сборку, только когда имеет смысл это делать, но не откладывайте внесение исправлений надолго.<br><br>Требуйте, чтобы разработчики проводили дымовое тестирование своего кода перед его добавлением в систему.<br><br>Создайте область промежуточного хранения кода, который следует добавить к сборке.<br><br>Назначьте наказание за нарушение сборки.<br><br>Выпускайте сборки по утрам.<br><br>Создавайте сборку и проводите дымовой тест даже в экстремальных условиях.<br><br>Под "непрерывной" понимается "по крайней мере ежедневная" интеграция.<br><br>До 40% времени программист тратит на редактирование исходного кода.<br><br>Передовой набор инструментов позволяет повысить производительность более, чем на 50%.<br><br>20% инструментария используются в 80% случаев.<br><br>Хорошее визуальное форматирование показывает логическую структуру программы.<br><br>Абзац кода должен содержать только взаимосвязанные операторы, выполняющие одно задание.<br><br>Начало нового абзаца в коде нужно указывать с помощью пустой строки.<br><br>Оптимальное число пустых строк в программе - 16%.<br><br>Операторы выделяются отступами, когда они следуют после выражения, от которого логически зависят.<br><br>Оптимальными являются отступы из 2-4 пробелов.<br><br>Формируйте блоки из 1 оператора единообразно.<br><br>В сложных выражениях размещайте каждое условие на отдельной строке.<br><br>Избегайте операторов goto.<br><br>Не используйте форматирование в конце строки в виде исключения для операторов case.<br><br>Используйте пробелы, чтобы сделать читаемыми логические выражения.<br><br>Используйте пробелы, чтобы сделать читаемыми обращения к массиву.<br><br>Используйте пробелы, чтобы сделать читаемыми аргументы методов.<br><br>Сделайте так, чтобы незавершенность выражения была очевидна.<br><br>Располагайте сильно связанные элементы вместе.<br><br>При переносе строк в вызове метода используйте отступ стандартного размера.<br><br>Упростите поиск конца строки с продолжением.<br><br>При переносе строк в управляющем выражении делайте отступ стандартного размера.<br><br>Не выравнивайте правые части выражений присваивания.<br><br>При переносе строк в выражениях присваивания применяйте отступы стандартного размера.<br><br>Располагайте каждое объявление данных в отдельной строке.<br><br>Объявляйте переменные рядом с местом их первого использования.<br><br>Разумно упорядочивайте объявления.<br><br>Делайте в комментации такой же отступ, как и в соответствующем ему коде.<br><br>Отделяйте каждый комментарий хотя бы одной пустой строкой.<br><br>Используйте пустые строки для разделения составных частей метода.<br><br>Используйте стандартный отступ для аргументов метода.<br><br>Если файл содержит более 1 класса, четко определяйте границы каждого класса.<br><br>Помещайте каждый класс в отдельный файл.<br><br>Называйте файл в соответствии с именем класса.<br><br>Отделяйте методы друг от друга с помощью хотя бы 2 пустых строк.<br><br>Упорядочивайте методы по алфавиту.<br><br>Используйте стиль комментирования, который легко поддерживать.<br><br>Используйте содержательные комментарии.<br><br>Избегайте комментариев, высосанных из пальца.<br><br>Не используйте комментарии в концах строк, относящиеся к нескольким строкам кода.<br><br>Используйте комментарии в концах строк для пояснения объявлений данных.<br><br>Не используйте комментарии в концах строк для вставки пометок во время сопровождения ПО.<br><br>Используйте комментарии в концах строк для обозначения концов блоков.<br><br>Описывайте цель блока кода, следующего за комментарием.<br><br>Во время документирования сосредоточьтесь на самом коде.<br><br>Придумывая комментарий абзаца, стремитесь ответить на вопрос "почему", а не "как".<br><br>Используйте комментарии для подготовки читателя кода к последующей информации.<br><br>Не размножайте комментарии без необходимости.<br><br>Документируйте сюрпризы.<br><br>Избегайте сокращений.<br><br>Проведите различие между общими и детальными комментариями.<br><br>Комментируйте все, что имеет отношение к ошибкам или недокументированным возможностям языка или среды.<br><br>Указывайте в комментариях единицы измерения численных величин.<br><br>Указывайте в комментариях диапазоны допустимых значений численных величин.<br><br>Комментируйте смысл закодированных значений.<br><br>Комментируйте ограничения входных данных.<br><br>Документируйте флаги до уровня отдельных битов.<br><br>Включайте в комментарии, относящиеся к переменной, имя переменной.<br><br>Документируйте глобальные данные.<br><br>Пишите комментарий перед каждым оператором if, блоком case, циклом или группой операторов.<br><br>Комментируйте завершение каждой управляющей структуры.<br><br>Рассматривайте комментарии в концах циклов как предупреждения о сложности кода.<br><br>Располагайте комментарии близко к описываемому ими коду.<br><br>Описывайте каждый метод одним-двумя предложениями перед началом метода.<br><br>Документируйте параметры в местах их объявления.<br><br>Используйте утилиты документирования кода.<br><br>Проведите различие между входными и выходными данными.<br><br>Документируйте выраженные в интерфейсе предположения.<br><br>Комментируйте ограничения методов.<br><br>Документируйте глобальные результаты выполнения метода.<br><br>Документируйте источники используемых алгоритмов.<br><br>Используйте комментарии для маркирования частей программы.<br><br>Опишите подход к проектированию класса.<br><br>Опишите ограничения класса, предположения о его использовании и так далее.<br><br>Прокомментируйте интерфейс класса.<br><br>Не документируйте в интерфейсе класса детали реализации.<br><br>Опишите назначение и содержание каждого файла.<br><br>Укажите в блочном комментарии свои имя/фамилию, адрес электронной почты и номер телефона.<br><br>Включите в файл тег версии.<br><br>Включите в блочный комментарий юридическую информацию.<br><br>Присвойте файлу имя, характеризующее его содержание.<br><br>Лучшие программисты создают программы в 10 раз быстрее коллег.<br><br>Изучите процесс разработки.<br><br>Экспериментируйте.<br><br>Читайте о решении проблем.<br><br>Анализируйте и планируйте, прежде чем действовать.<br><br>Изучайте успешные проекты.<br><br>Читайте.<br><br>Читайте другие книги и периодические издания.<br><br>Общайтесь с единомышленниками.<br><br>Постоянно стремитесь к профессиональному развитию.<br></div></article><br><footer>&copy;&nbsp;<i>Copyright&nbsp;<a href="https://алексейлот.рф">алексейлот.рф</a>&nbsp;-&nbsp;возьми главную ноту</i></footer></body></html>
